iT邦幫忙

2024 iThome 鐵人賽

DAY 20
0
Modern Web

Svelte 的奇妙冒險系列 第 20

[Svelte 的奇妙冒險] Day 20 - 錯誤處理

  • 分享至 

  • xImage
  •  

+error.svelte

在 SvelteKit 中我們可以利用 +error.svelte 來設定遇到錯誤時該如何顯示

<!-- in src/routes/+error.svelte -->
<script lang="ts">
	import { page } from '$app/stores';
</script>

<h1>status:{$page?.status}</h1>
<h1>message:{$page?.error?.message}</h1>

然後我們直接訪問一個不存在的頁面假設是 http://localhost:5173/page-not-exist

然後它也能處理在 +page.ts 以及 +layout.ts 發生的錯誤,這時先新增 src/routes/day20/+page.ts 以及 +page.svelte

// in src/routes/day20/+page.ts
import { error } from '@sveltejs/kit';
import type { PageLoad } from './$types';

export const load: PageLoad = ({ params }) => {
	console.log('+page.ts load', params);

	error(401, 'Unauthorized');
};

<!-- in src/routes/day20/+page.svelte -->

<h1>Day 20</h1>

然後訪問 http://localhost:5173/day20 會看到以下畫面而不是如 +page.svelte 那樣的有一個 h1 的大標題。

+error.svelte 也能在每個路由(資料夾)都設定

<!-- in src/routes/day20/+error.svelte -->

<h1>Error Page in <span class="text-error">src/routes/day20/+error.svelte</span></h1>


這時再進去一次 http://localhost:5173/day20 會發現畫面變成了這樣

那如果我們再新增一個子頁面及它的 load 呢?

<!-- in src/routes/day20/foo/+page.svelte -->
<h1>day20/foo</h1>

// in src/routes/day20/foo/+page.ts

import { error } from '@sveltejs/kit';
import type { PageLoad } from './$types';

export const load: PageLoad = ({ params }) => {
	console.log('foo/+page.ts load', params);

	error(401, 'Unauthorized');
};

沒錯畫面依然是長這樣

也就是說 +page.ts 發生錯誤時會從「自己的目錄開始找最近的 +error.svelte 來顯示,如果沒找到就往上一層找,直到找到為止」

現在來新增 +layout.ts 而且也故意讓它發生錯誤

// in src/routes/day20/+layout.ts
import { error } from '@sveltejs/kit';
import type { PageLoad } from './$types';

export const load: PageLoad = ({ params }) => {
	console.log('+page.ts load', params);

	error(401, 'Unauthorized');
};

會發現錯誤並不是顯示 routes/day20/+error.svelte 而是變成了 routes/+error.svelte 了,這是因為 +layout.ts 它會直接「以+layout.ts 的路徑往上層開始找 +error.svelte

特別說明一下,是 +layout.ts 的路經的上一層開始也就是說 routes/day20/+layout.ts發生錯誤是會找到 routes/+error.svelte ,所以就算是我訪問了routes/day20/foo/bar/baz/+page.svelte ,依然是以發生錯誤的 +layout.ts 的所在位置的上一層開始找,跟我們實際上訪問的 URL 沒太大的關係

其實 +error.svelte 就有點像是 error boundary 的概念,在處理錯誤時會在最近的 boundary 處理錯誤,所以假設發生錯誤時 +page.ts 發生錯誤時就是+page.ts 所在位置開始尋找離它最近的 boundary,而 +layout.ts 發生錯誤時就是以 +layout.ts 所在位置的上一層開始找離它最近的 boundary。

如果要直接以這份 code 來試玩的話記得把 +layout.tserror 註解掉才能正常顯示 day20/+error.svelte


參考資料

source code

https://github.com/toddLiao469469/30days-for-svelte5/tree/main/src/routes/day20


上一篇
[Svelte 的奇妙冒險] Day 19 - SvelteKit 中的路由 (4)
下一篇
[Svelte 的奇妙冒險] Day 21 - 表單
系列文
Svelte 的奇妙冒險30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言